--[[
 
	Author: Zachary Coulombe
	Org:	Husson University
	Lead:	Dr. Gerald Wright

	Lang:   C#
	Proj:	Platformer Game
	File:	Main

	Summary: This file is the main entry point for the platformer game
			 application.


	Edit History:
	------------------------------------------------------------------
	Initials  Date:    ver.    Notes:
	-------- --------  ----    ------------------------------------------
	 ZC      02/05/15  1.0     - initial writing
					           - Add Player object
					           - Add Move Left ability
					           - Add Move Right Ability
					           - Add Friction
					           - Add Gravity
					           - Add object ground
					           - Add Collision
					           - Add Crouch Ability
					           - Test
	IAM		 02/14/15  1.1     - Implemented tiled background
							   - Re-ordered draw order to hide 
							     background
	-------- ------  -----------------------------------------------]]

function love.load()
	
	-- The Variables the hold the length of
	-- the Window in pixels
	WindowWidth = love.window.getWidth()
	WindowHeight = love.window.getHeight()
	
	--[[ Debug Error Message. I use this variable to
	display text when I want to make sure a part of
	the code is working --]] 
	error = ""
	
	-- Basic Objects table to store objects in the level
	objects = {}
	
	-- The Ground Object
	objects.ground = {}
	objects.ground.Width = WindowWidth
	objects.ground.Height = 25
	objects.ground.X = 0
	objects.ground.Y = WindowHeight - objects.ground.Height
	
	-- The Player Object
	player = {}
	player.isColiding = false
	player.Width = 25
	player.Height = 25
	player.CrouchStength = 10
	player.JumpStrength = 15
	player.X = WindowWidth/2
	player.Y = WindowHeight/2
	player.MoveSpeed = 10
	player.Velocity = {}
	player.Velocity.X = 0
	player.Velocity.Y = 0
	player.Acceleration = {}
	player.Acceleration.X = 0
	player.Acceleration.Y = 0
	player.Mass = 10
	
	-- Coefficient of Friction used in Physics calculations
	CoefficientFriction = .2
	gravity = 1
	
	-- The background object
	background = love.graphics.newImage("images/Forest.png")
end

function love.update(dt)
	
	-- Gather Input Vectors
	MoveRight(dt)
	MoveLeft(dt)
	Jump(dt)
	Crouch(dt)
	--[[ This section gathers all of the input vectors
	into their resulting vectors. There is a resulting
	vectors in the X and Y directions. Below is a graphics
	that shows all the vectors before the final resulting/
	vector has been calculated:
	
			     +
			Jump |
			     |
	         MoveLeft  /---\
		    <------|   |------>
			   \---/  MoveRight
		             |
			     | Crouch
			     +
						
	--]]

	
	-- Friction
	CalcFriction(dt)
	
	
	-- Gravity
	player.Velocity.Y = player.Velocity.Y + gravity
	
	-- Calc Colisions
	CalcColision(dt)
	
	--[[ Acceleration
		
		Acceleration = ResultingVelocity * Mass * Time
	
	--]]
	player.Acceleration.X = player.Velocity.X * player.Mass * dt
	player.Acceleration.Y = player.Velocity.Y * player.Mass * dt
	
	
	-- Update Position
	player.X = player.X + player.Acceleration.X
	player.Y = player.Y + player.Acceleration.Y
end

function love.draw()
	--[[ This function is the function call to
	the renderer. Every line in this function will
	draw an image or object onto the screen.--]]
	
	
	-- Draw the ground
	love.graphics.rectangle("fill",objects.ground.X,objects.ground.Y,objects.ground.Width,objects.ground.Height)	
	
	-- Draw a tiled background
	for i = 0, love.graphics.getWidth() / background:getWidth() do
        for j = 0, love.graphics.getHeight() / background:getHeight() do
            love.graphics.draw(background, i * background:getWidth(), j * background:getHeight())
        end
    end
	
	
	-- Draw a rectangle which will represent the player
	love.graphics.rectangle("fill",player.X,player.Y,player.Width,player.Height)
	
	-- Draw the error message when necessary.
	-- This is only used for debuging.
	love.graphics.print(error, WindowWidth/2,WindowHeight/2)
	

	

	
end

function MoveRight(dt)
	-- This function allows the player to move right
	-- if the right key or d key are down than...
	if(love.keyboard.isDown("right", "d")) then
	
		-- Move the player to the Right
		player.Velocity.X = player.Velocity.X + player.MoveSpeed
	end
end
function MoveLeft(dt)
	-- This function allows the player to move right
	-- if the left key or a key are down than...
	if(love.keyboard.isDown("left", "a")) then
	
		-- Move the player to the Left
		player.Velocity.X = player.Velocity.X - player.MoveSpeed
	end
end
function Jump(dt)
	-- This function allows the player to jump
	-- if the up key or w key are down than...
	if(love.keyboard.isDown("up", "w")) then
		
		-- if the player is colliding with and
		-- object than...
		if player.isColiding == true then
		
			-- Jump
			player.Velocity.Y = player.Velocity.Y - player.JumpStrength
		end
	end
end
function Crouch(dt)
	-- This function allows the player to crouch
	-- If the the down key or the s key are registered
	-- as down, than...
	if(love.keyboard.isDown("down", "s")) then
	
		-- Crouch
		player.Velocity.Y = player.Velocity.Y + player.CrouchStength
	end
end
function CalcFriction(dt)
	--This function imposes Friction on the player.
	
	--[[The formula for calculating the Frictional force
		applied to any object is as follows.
		
		Friction = Coefficient of Friction * Force
	
		The Coefficient of Friction is a product of the 
		material of the surface upon which the object rests.
		If the material is rough than the Coefficient of Friction
		will be high, but if the material is smooth than
		the Coefficient will be small.
		
		The Friction force operates opposite of the Force
		applied to the object as shown in the following
		diagram.   		
			          /---\
			Friction  |   |------>       Coefficient of Friction
			     <----\---/  Force		/
		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
	]]--
	FrictionalForce = CoefficientFriction*player.Velocity.X
	
	-- apply the Frictional Force in the Opposite direction
	-- as the Movement Force
		player.Velocity.X = player.Velocity.X - FrictionalForce	--else

end
function CalcColision(dt)
	--[[ This function will check to see if there is
		a collision.--]]
		
	--[[ We calculate the collision point of the player
		by taking Position of the topleft corner of 
		the player rectangle and adding the player height.
		
		Player Collision Point = TopLeftCornerPoint + Player Height
		
	--]]
	PlayerColisionPoint = player.Y + player.Height
	
		-- If the Player Collision Point intersects the
		-- object than...
		if PlayerColisionPoint >= objects.ground.Y then
		
			-- Set isColliding to true
			player.isColiding = true
			
			-- Detect by how much the two objects are intersecting
			GroundPlayerDifference = PlayerColisionPoint - objects.ground.Y
			
			-- if gravity is effecting the objects than...
			if player.Velocity.Y > 0 then
			
				--[[We then adjust the player so that the objects no
					longer collide.
								Ground
						/---\  _       /
				     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  								 
						|   |  |<-GroundPlayer
						\---/  _  Difference
					       ^  |
				       Opposite|  | Gravity
				       Force   |  +
					
					In order to make sure that the objects
					no longer collide we follow the Newton's
					Third Law of Motion which states.
					
						For every action there is an equal
						and opposite reaction.
						
					This law allows us to add the inverse of
					current Velocity plus the Ground Player 
					Difference. --]]
				player.Velocity.Y = player.Velocity.Y - (player.Velocity.Y + GroundPlayerDifference)
			end
		else
			-- Else if there is no collision do not allows
			-- the player to jump.
			player.isColiding = false
			
		end
	
end
